package com.ricchieri.manage.bean;

import java.util.Calendar;
import java.util.Date;
import java.util.Map;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;

import org.primefaces.context.RequestContext;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultScheduleModel;
import org.primefaces.model.ScheduleModel;

import com.ricchieri.common.BusinessSettings;
import com.ricchieri.common.CustomScheduleEvent;
import com.ricchieri.filter.CharterFilter;
import com.ricchieri.filter.ScheduleCharterFilter;
import com.ricchieri.filter.TripFilter;
import com.ricchieri.filter.UserFilter;
import com.ricchieri.lazymodel.AddScheduleLazyDataModel;
import com.ricchieri.lazymodel.ScheduleLazyModel;
import com.ricchieri.model.Charter;
import com.ricchieri.model.Schedule;
import com.ricchieri.model.ScheduleCharter;
import com.ricchieri.model.Trip;
import com.ricchieri.model.User;
import com.ricchieri.service.interf.ICharterService;
import com.ricchieri.service.interf.IScheduleCharterService;
import com.ricchieri.service.interf.ITripService;
import com.ricchieri.service.interf.IUserService;
import com.ricchieri.util.DateUtil;
import com.ricchieri.util.FacesUtil;
import com.ricchieri.util.StringUtils;

@ManagedBean(name = "addScheduleMB")
@ViewScoped
public class AddScheduleManageBean extends GenericManageBean {
	private static final long serialVersionUID = -7001021047911879866L;

	@ManagedProperty(value = "#{TripService}")
	ITripService tripService;

	@ManagedProperty(value = "#{CharterService}")
	ICharterService charterServices;

	@ManagedProperty(value = "#{UserService}")
	IUserService userService;

	@ManagedProperty(value = "#{ScheduleCharterService}")
	IScheduleCharterService scheduleCharterService;

	private Map<String, String> trips = null;
	private Map<String, String> charters = null;
	private Map<String, String> users = null;

	private ScheduleCharterFilter scheduleCharterFilter = new ScheduleCharterFilter();
	private String selectedFrecuency = BusinessSettings.FRECUENCY_NONE;
	private ScheduleModel eventModel = new DefaultScheduleModel();
	private CustomScheduleEvent event = new CustomScheduleEvent();
	private ScheduleLazyModel scheduleLazyModel;
	private Boolean isEditableEndDate = Boolean.FALSE;

	public void setTrips(Map<String, String> trips) {
		this.trips = trips;
	}

	public ITripService getTripService() {
		return tripService;
	}

	public void setTripService(ITripService tripService) {
		this.tripService = tripService;
	}

	public Map<String, String> getTrips() {
		if (trips == null) {
			trips = getTripService().getComboTrips();
		}

		return trips;
	}

	private Trip obtainTrip(String id) {
		TripFilter tripFilter = new TripFilter();
		tripFilter.setId(Integer.valueOf(id));
		return getTripService().getTripById(tripFilter);
		
	}

	public CustomScheduleEvent getEvent() {
		return event;
	}

	public void setEvent(CustomScheduleEvent event) {
		this.event = event;
	}

	public void addEvent(ActionEvent actionEvent) {

		if (validateForm()) {

			CustomScheduleEvent eventWrapper = (CustomScheduleEvent) event;
			eventWrapper.setStartDate(DateUtil.setTimeFromDate(
					eventWrapper.getStartDate(), eventWrapper.getTime()));
			eventWrapper.setEndDate(DateUtil.setTimeFromDate(
					eventWrapper.getEndDate(), eventWrapper.getTime()));
			eventWrapper.setTitle(" ");
			if (event.getId() == null && event.getScheduleCharter() == null) {
				this.generateFrecuency(eventWrapper);
			} if(event.getScheduleCharter() == null) {				
				eventModel.updateEvent(eventWrapper);
			} else {
				ScheduleCharter schedule = eventWrapper.getScheduleCharter();
				schedule.setCharter(obtainCharter(eventWrapper.getSelectedCharter()));
				schedule.setUser(obtainUser(eventWrapper.getSelectedUser()));
				Schedule schedul = new Schedule(event.getStartDate(),
						DateUtil.convertToTime(event.getTime()));
				schedule.setSchedule(schedul);
				getScheduleCharterService().updateScheduleCharter(schedule);
			}

			event = new CustomScheduleEvent();
		}
	}

	public void onEventSelect(SelectEvent selectEvent) {
		event = (CustomScheduleEvent) selectEvent.getObject();
		isEditableEndDate = Boolean.TRUE;
	}

	public void onDateSelect(SelectEvent selectEvent) {
		event = new CustomScheduleEvent("", (Date) selectEvent.getObject(),
				null, null, null, null);
		event.setEndDate(event.getStartDate());
		isEditableEndDate = Boolean.TRUE;
	}

	public ScheduleModel getEventModel() {
		return eventModel;
	}

	public void setEventModel(ScheduleModel eventModel) {
		this.eventModel = eventModel;
	}

	public String save() {
		ScheduleCharter scheduleCharter;
		Schedule schedule;
		CustomScheduleEvent event;

		for (int i = 0; i < eventModel.getEvents().size(); i++) {
			event = (CustomScheduleEvent) eventModel.getEvents().get(i);
			scheduleCharter = new ScheduleCharter();
			schedule = new Schedule(event.getStartDate(),
					DateUtil.convertToTime(event.getTime()));
			scheduleCharter.setTrip(obtainTrip(this.getScheduleCharterFilter()
					.getTrip()));
			scheduleCharter.setSchedule(schedule);
			scheduleCharter.setCharter(obtainCharter(event.getSelectedCharter()));
			scheduleCharter.setUser(obtainUser(event.getSelectedUser()));
			scheduleCharterService.insertScheduleCharter(scheduleCharter);
		}
		return BusinessSettings.SUCCESS;
	}

	public void generateFrecuency(CustomScheduleEvent eventWrapper) {

		if (getSelectedFrecuency().equals(BusinessSettings.FRECUENCY_NONE)) {
			eventWrapper.setEndDate(DateUtil.setTimeFromDate(
					eventWrapper.getStartDate(), eventWrapper.getTime()));
			eventModel.addEvent(eventWrapper);
		} else if (getSelectedFrecuency().equals(
				BusinessSettings.FRECUENCY_ALL_DAYS)) {
			int numDays = DateUtil.daysBetween(eventWrapper.getStartDate(),
					eventWrapper.getEndDate());
			for (int i = 0; i <= numDays; i++) {
				eventModel.addEvent(new CustomScheduleEvent(" ", DateUtil
						.addDays(eventWrapper.getStartDate(), i), DateUtil
						.addDays(eventWrapper.getStartDate(), i), eventWrapper
						.getSelectedCharter(), eventWrapper.getTime(),
						eventWrapper.getSelectedUser()));
			}
		} else {
			int numDays = DateUtil.daysBetween(eventWrapper.getStartDate(),
					eventWrapper.getEndDate());
			int weeks = numDays / 7;

			for (int i = 0; i <= weeks; i++) {
				eventModel.addEvent(new CustomScheduleEvent(" ", DateUtil
						.addDays(eventWrapper.getStartDate(), i * 7), DateUtil
						.addDays(eventWrapper.getStartDate(), i * 7),
						eventWrapper.getSelectedCharter(), eventWrapper
								.getTime(), eventWrapper.getSelectedUser()));
			}
		}
	}

	public void reset() {
		event = new CustomScheduleEvent();
		setSelectedFrecuency(BusinessSettings.FRECUENCY_NONE);
	}

	public void deleteEvent() {
		if (event.getScheduleCharter()==null){
			eventModel.deleteEvent(event);		
		}else{
			getScheduleCharterService().delete(event.getScheduleCharter());
		}
	}

	private Boolean validateForm() {
		Boolean isValid = Boolean.TRUE;

		if (event.getStartDate().after(event.getEndDate())) {
			FacesUtil.addErrorMsg("addSchedule:to", "schduleDateRangeWrong");
			isValid = Boolean.FALSE;
		}
		
		if (StringUtils.isEmpty(event.getSelectedCharter())){
			FacesUtil.addErrorMsg("addSchedule:charter", "requiredCharter");
			isValid = Boolean.FALSE;
		}

		RequestContext context = RequestContext.getCurrentInstance();
		context.addCallbackParam("isValid", isValid);
		return isValid;
	}

	public ICharterService getCharterServices() {
		return charterServices;
	}

	public void setCharterServices(ICharterService charterServices) {
		this.charterServices = charterServices;
	}

	public Map<String, String> getCharters() {
		if (charters == null) {
			charters = getCharterServices().getComboCharters();
		}

		return charters;
	}

	private Charter obtainCharter(String id) {
		CharterFilter charterFilter = new CharterFilter();
		charterFilter.setId(Integer.valueOf(id));
		return getCharterServices().getCharterById(charterFilter  );
	}

	public void setCharters(Map<String, String> charters) {
		this.charters = charters;
	}

	public IUserService getUserService() {
		return userService;
	}

	public void setUserService(IUserService userService) {
		this.userService = userService;
	}

	public void setUsers(Map<String, String> users) {
		this.users = users;
	}

	public Map<String, String> getUsers() {
		if (users == null) {
			UserFilter userFilter = new UserFilter();
			userFilter.setRole(BusinessSettings.ROLE_DRIVER);
			
			users = getUserService().getComboUserByRole(userFilter);
		}

		return users;
	}

	private User obtainUser(String id) {
		if(StringUtils.isNotEmpty(id)) {
			UserFilter userFilter = new UserFilter();
			userFilter.setRole(BusinessSettings.ROLE_DRIVER);
			userFilter.setId(Integer.valueOf(id));
			
			return getUserService().getUserById(userFilter);
		}
		return null;
	}

	public IScheduleCharterService getScheduleCharterService() {
		return scheduleCharterService;
	}

	public void setScheduleCharterService(
			IScheduleCharterService scheduleCharterService) {
		this.scheduleCharterService = scheduleCharterService;
	}

	public String getSelectedFrecuency() {
		return selectedFrecuency;
	}

	public void setSelectedFrecuency(String selectedFrecuency) {
		this.selectedFrecuency = selectedFrecuency;
	}

	public ScheduleCharterFilter getScheduleCharterFilter() {
		return scheduleCharterFilter;
	}

	public void setScheduleCharterFilter(
			ScheduleCharterFilter scheduleCharterFilter) {
		this.scheduleCharterFilter = scheduleCharterFilter;
	}

	public ScheduleLazyModel getScheduleLazyModel() {

		if (scheduleLazyModel == null) {
			scheduleLazyModel = new AddScheduleLazyDataModel(
					getScheduleCharterService(), getScheduleCharterFilter(),
					getEventModel());
		}
		return scheduleLazyModel;
	}

	public void setScheduleLazyModel(ScheduleLazyModel scheduleLazyModel) {
		this.scheduleLazyModel = scheduleLazyModel;
	}

	public String resetSchedule() {
		return BusinessSettings.SUCCESS;
	}

	public void changeTrip() {
		setScheduleLazyModel(null);
		setEventModel(new DefaultScheduleModel());
	}

	public void changeFrecuency() {
		if (getSelectedFrecuency().equals(BusinessSettings.FRECUENCY_NONE)
				|| StringUtils.isNotEmpty(event.getId())) {
			event.setEndDate(event.getStartDate());
			isEditableEndDate = Boolean.TRUE;
		} else {
			isEditableEndDate = Boolean.FALSE;
		}
	}

	public Boolean getIsEditableEndDate() {
		return isEditableEndDate;
	}

	public void setIsEditableEndDate(Boolean isEditableEndDate) {
		this.isEditableEndDate = isEditableEndDate;
	}
	
	public Boolean isEventExpired() {
		Calendar calActual = Calendar.getInstance();
		calActual.set(Calendar.HOUR_OF_DAY, 0);
		calActual.set(Calendar.MILLISECOND, 0);
		calActual.set(Calendar.SECOND, 0);
		calActual.set(Calendar.MINUTE, 0);
		
		if(event != null && event.getStartDate() != null) {
			
			Calendar calStart = Calendar.getInstance();
			calStart.setTime(event.getStartDate());
			calStart.set(Calendar.HOUR_OF_DAY, 0);
			calStart.set(Calendar.MILLISECOND, 0);
			calStart.set(Calendar.SECOND, 0);
			calStart.set(Calendar.MINUTE, 0);
			
			return calActual.getTime().after(calStart.getTime());
		}
		return Boolean.FALSE;
	}
}
